package com.czk.transational;

import com.alibaba.fastjson.JSONObject;
import com.czk.netty.NettyClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Component
public class CzkTransactionManager {


    private static NettyClient nettyClient;
    /**
     * 绑定事务
     */
    private static ThreadLocal<CzkTransaction> current = new ThreadLocal<>();
    /**
     * 同一个线程调用
     * 利用threadLocal绑定资源，所以此时同一个线程获取的groupId是一致的
     */
    private static ThreadLocal<String> currentGroupId = new ThreadLocal<>();
    /**
     * 都要threadLocal来绑定线程资源
     */
    private static ThreadLocal<Integer> transactionCount = new ThreadLocal<>();

    @Autowired
    public void setNettyClient(NettyClient nettyClient) {
        CzkTransactionManager.nettyClient = nettyClient;
    }

    public static Map<String, CzkTransaction> LB_TRANSACION_MAP = new HashMap<>();

    /**
     * 创建事务组，并且返回groupId
     *
     * @return
     */
    public static String createLbTransactionGroup() {
        String groupId = UUID.randomUUID().toString();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("groupId", groupId);
        jsonObject.put("command", "create");
        nettyClient.send(jsonObject);
        System.out.println("创建事务组");

        currentGroupId.set(groupId);
        return groupId;
    }

    /**
     * 创建子事务
     *
     * @param groupId
     * @return
     */
    public static CzkTransaction createLbTransaction(String groupId) {
        String transactionId = UUID.randomUUID().toString();
        CzkTransaction czkTransaction = new CzkTransaction(groupId, transactionId);
        LB_TRANSACION_MAP.put(groupId, czkTransaction);
        current.set(czkTransaction);
        addTransactionCount();

        System.out.println("创建事务");

        return czkTransaction;
    }

    /**
     * 注册事务
     *
     * @param czkTransaction
     * @param isEnd
     * @param czkTransactionType
     * @return
     */
    public static CzkTransaction addLbTransaction(CzkTransaction czkTransaction, Boolean isEnd, CzkTransactionType czkTransactionType) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("groupId", czkTransaction.getGroupId());
        jsonObject.put("transactionId", czkTransaction.getTransactionId());
        jsonObject.put("transactionType", czkTransactionType);
        jsonObject.put("command", "add");
        jsonObject.put("isEnd", isEnd);
        jsonObject.put("transactionCount", CzkTransactionManager.getTransactionCount());
        nettyClient.send(jsonObject);
        System.out.println("添加事务");
        return czkTransaction;
    }

    public static CzkTransaction getLbTransaction(String groupId) {
        return LB_TRANSACION_MAP.get(groupId);
    }

    public static CzkTransaction getCurrent() {
        return current.get();
    }

    public static String getCurrentGroupId() {
        return currentGroupId.get();
    }

    public static void setCurrentGroupId(String groupId) {
        currentGroupId.set(groupId);
    }

    public static Integer getTransactionCount() {
        return transactionCount.get();
    }

    public static void setTransactionCount(int i) {
        transactionCount.set(i);
    }

    public static Integer addTransactionCount() {
        int i = (transactionCount.get() == null ? 0 : transactionCount.get()) + 1;
        transactionCount.set(i);
        return i;
    }
}
